home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / tool / dmove86 / dmove86.c < prev    next >
Text File  |  1995-02-15  |  10KB  |  540 lines

  1. /*
  2.  
  3. dmove86 Version 2.00c
  4. Copyright (c) 1993,94 Delmonta
  5.  
  6. dmove86.c -- メインルーチン
  7.  
  8. */
  9.  
  10. #define    MAIN
  11.  
  12. #include<stdio.h>
  13. #include<dos.h>
  14. #include<stdlib.h>
  15. #include<ctype.h>
  16. #include<signal.h>
  17. #include"dmove86.h"
  18.  
  19. /*-----------------------------------変数------------------------------------*/
  20. static    unsigned    Pagenum,Lastnum;/* ページ数・最終ページのエントリ数 */
  21. static    unsigned    Page=0,Pos=0;    /* 現在のページ番号とカーソル位置  */
  22. static    unsigned    Selected=-1;    /* 選択され反転表示されている番号  */
  23. static    int        Ischanged = 0;
  24. /*---------------------------------------------------------------------------*/
  25. static    int    isok(void)
  26. {
  27.     if    (!Ischanged)
  28.         return 1;
  29.  
  30. rep:
  31.     switch    (dm_errmes("\aデータを保存していません よろしいですか(y/n)"))
  32.     {
  33.     case 'N':
  34.     case 'n':
  35.     case '\033':
  36.         return 0;
  37.     case 'Y':
  38.     case 'y':
  39.         return 1;
  40.     default:
  41.         goto rep;
  42.     }
  43. }
  44.  
  45. /*---------------------------------画面表示----------------------------------*/
  46. static    void    putfilename(p)        /* 画面にファイル名を表示          */
  47. int        p;
  48. {
  49.     printf("\033[%d;%df ",p/6+3,(p%6)*13+1);
  50.  
  51.     if    (Page*96+p == Selected)
  52.         printf("\033[7");    /* 最後の'm'はまだつけない */
  53.     else
  54.         printf("\033[0");
  55.  
  56.     if    (Dirtbl[Page*96+p]->filename[0]=='\xe5')
  57.         printf("m::::::::.:::");
  58.     else
  59.     {
  60.         int    i;
  61.  
  62.         if    (Dirtbl[Page*96+p]->attr & _A_SUBDIR)
  63.             printf(";32m");        /* ディレクトリは緑 */
  64.         else if    (Dirtbl[Page*96+p]->attr & _A_VOLID)
  65.             printf(";35m");        /* ボリュームIDは紫 */
  66.         else if    (Dirtbl[Page*96+p]->attr & _A_SYSTEM)
  67.             printf(";31m");        /* システムファイルは赤 */
  68.         else
  69.             printf(";37m");        /* そのほかは白 */
  70.  
  71.         for    (i=0 ; i<8 ; i++)
  72.         {
  73.             if    (i==0 && Dirtbl[Page*96+p]->filename[0]==5)
  74.                 putchar('\xe5');
  75.             else
  76.                 putchar(Dirtbl[Page*96+p]->filename[i]);
  77.         }
  78.  
  79.         putchar('.');
  80.  
  81.         for    (i=0 ; i<3 ; i++)
  82.             putchar(Dirtbl[Page*96+p]->extname[i]);
  83.     }
  84.     printf(" \n\033[0;37m");
  85. }
  86.  
  87. static    void    putpage(n)    /* ページ表示 */
  88. int        n;        /* n!=0なら一度画面を消す */
  89. {
  90.     int        i;
  91.  
  92.     printf("\033[3;1f");
  93.  
  94.     if    (n)
  95.         for    (i=0 ; i<16 ; i++)
  96.             printf("\033[2K\n");
  97.  
  98.     for    (i=0 ; i<96 ; i++)
  99.     {
  100.         if    (Page==Pagenum-1 && i==Lastnum)
  101.             break;
  102.         else
  103.             putfilename(i);
  104.     }
  105. }
  106.  
  107. void    putcursor(void)
  108. {
  109. static    int        oldx = -1,
  110.             oldy = -1;
  111.  
  112.     if    (oldx != -1)
  113.     {
  114.         printf("\033[%d;%df",oldy+3,oldx*13+1);
  115.         putchar(' ');
  116.         printf("\033[%d;%df",oldy+3,oldx*13+13+1);
  117.         putchar(' ');
  118.     }
  119.  
  120.     oldx = Pos%6;
  121.     oldy = Pos/6;
  122.  
  123.     printf("\033[%d;%df",oldy+3,oldx*13+1);
  124.     putchar('<');
  125.     printf("\033[%d;%df",oldy+3,oldx*13+13+1);
  126.     putchar('>');
  127. }
  128.  
  129. /*----------------------------カーソル移動とキー入力-------------------------*/
  130. static    char    movecursor(flag)
  131. int        flag;            /* カーソル・スペース・ESC以外を受け付けるか */
  132. {
  133.     int    c;
  134.  
  135. LOOP:
  136.     putcursor();
  137.  
  138.     c = dm_getch();
  139.  
  140.     if    (c == '\3')
  141.         endscreen();
  142.  
  143.     if    (c == '\x1a')
  144.         endscreen();
  145.  
  146.     switch    (c)
  147.     {
  148.     case RIGHTKEY:
  149.         Pos++;
  150.         if    (Pos==96 || (Page==Pagenum-1 && Pos==Lastnum) )
  151.             Pos=0;
  152.         break;
  153.  
  154.     case LEFTKEY:
  155.         if    (Pos==0)
  156.         {
  157.             if    (Page==Pagenum-1)
  158.                 Pos = Lastnum-1;
  159.             else
  160.                 Pos = 95;
  161.         }
  162.         else
  163.             Pos--;
  164.         break;
  165.  
  166.     case UPKEY:
  167.         if    (Pos>=6)
  168.             Pos = Pos-6;
  169.         break;
  170.  
  171.     case DOWNKEY:
  172.         if    (Pos>=96-6 || (Page==Pagenum-1 && Pos+6>=Lastnum) )
  173.             ;    /* Pos>=Lastnum-6では、Lastnum-6<0となって   */
  174.         else        /* Posがunsignedの為正確に判断できない場合有 */
  175.             Pos = Pos+6;
  176.         break;
  177.  
  178.     case '-':
  179.         if    (Page>=1)
  180.         {
  181.             Page--;
  182.             putpage(1);
  183.         }
  184.         break;
  185.  
  186.     case '+':
  187.         if    (Page<Pagenum-1)
  188.         {
  189.             Page++;
  190.  
  191.             if    (Page==Pagenum-1 && Pos>=Lastnum)
  192.                 Pos = Lastnum-1;
  193.  
  194.             putpage(1);
  195.         }
  196.         break;
  197.  
  198.     case ' ':
  199.         if    (Dirtbl[Page*96+Pos]->filename[0]!='.')
  200.             return c;
  201.         else
  202.             dm_errmes("\".\"や\"..\"に対しては操作できません.\a");
  203.         break;
  204.  
  205.     case '\033':
  206.         return c;
  207.  
  208.     default:
  209.         if    (flag)
  210.             return c;
  211.  
  212.         break;
  213.     }
  214.  
  215.     goto LOOP;
  216. }
  217.  
  218. /*--------------------------------各コマンド---------------------------------*/
  219. static    void    cmd_insert(void)
  220. {
  221.     int        i;
  222.     struct DIRENTRY    far *d;
  223.  
  224.     if    ((d=Dirtbl[Dirnum-1])->filename[0]=='\xe5')
  225.     {
  226.         for    (i=Dirnum-1 ; i>Page*96+Pos ; i--)
  227.             Dirtbl[i] = Dirtbl[i-1];
  228.  
  229.         Dirtbl[Page*96+Pos] = d;
  230.         Ischanged = 1;
  231.         putpage(0);
  232.     }
  233.     else
  234.         putchar('\a');
  235. }
  236.  
  237. static    void    cmd_delete(void)
  238. {
  239.     int        i;
  240.     struct DIRENTRY    far *d;
  241.  
  242.     if    ((d=Dirtbl[Page*96+Pos])->filename[0]=='\xe5')
  243.     {
  244.         for    (i=Page*96+Pos ; i<Dirnum-1 ; i++)
  245.             Dirtbl[i] = Dirtbl[i+1];
  246.  
  247.         Dirtbl[Dirnum-1] = d;
  248.         Ischanged = 1;
  249.         putpage(0);
  250.     }
  251.     else
  252.         putchar('\a');
  253. }
  254. static    void    cmd_exchange(void)
  255. {
  256.     int        i;
  257.     struct DIRENTRY    far *d;
  258.  
  259.     Selected = Page*96+Pos;
  260.  
  261.     putfilename(Pos);
  262.     if    (movecursor(0)==' ' && Selected!=Page*96+Pos)
  263.     {
  264.         d = Dirtbl[Selected];
  265.         Dirtbl[Selected] = Dirtbl[Page*96+Pos];
  266.         Dirtbl[Page*96+Pos] = d;
  267.         Ischanged = 1;
  268.     }
  269.  
  270.     if    (Selected/96 == Page)
  271.     {
  272.         i = Selected%96;
  273.         Selected = -1;
  274.         putfilename(i);
  275.     }
  276.     else
  277.         Selected = -1;
  278.  
  279.     putfilename(Pos);
  280. }
  281.  
  282. static    void    cmd_sort(void)
  283. {
  284.     Selected = Page*96+Pos;
  285.     putfilename(Pos);
  286.  
  287.     printf( "\033[19;1f\033[37mソート:終点を指定してください\n");
  288.  
  289.     if    (movecursor(0)==' ' && Selected!=Page*96+Pos)
  290.     {
  291.         unsigned int    s = Selected;
  292.         unsigned int    e = Page*96+Pos;
  293.  
  294.         if    (s>e)
  295.         {
  296.             register unsigned int    a = e;
  297.             e = s;
  298.             s = a;
  299.         }
  300.  
  301.         if    (dmsort(s,e))
  302.             Ischanged = 1;
  303.     }
  304.  
  305.     printf("\033[19;1f\033[2K");
  306.     Selected = -1;
  307.     putpage(0);
  308. }
  309.  
  310. static    void    cmd_help(void)
  311. {
  312.     #define    EL    "\033[2K  "    /* 各行の行頭 */
  313.     #define    AT    "\033[36m"    /* 水色 */
  314.     #define    NO    "\033[37m"    /* 白に戻す */
  315.  
  316.     printf( "\033[3;1f"
  317.     /* 0 */    EL "\n"
  318.     /* 1 */    EL "                        コマンドリスト\n"
  319.     /* 2 */    EL "\n"
  320.     /* 3 */    EL AT "[SPACE]" NO "       2つのファイルの位置を交換します\n"
  321.     /* 4 */    EL AT "H" NO "elp/" AT "[?]" NO "      この画面を表示します\n"
  322.     /* 5 */    EL AT "D" NO "elete        空白を削除します\n"
  323.     /* 6 */    EL AT "I" NO "nsert        空白を挿入します\n"
  324.     /* 7 */    EL AT "R" NO "ename        ファイル名等を変更します\n"
  325.     /* 8 */    EL AT "S" NO "ort          エントリをソートします\n"
  326.     /* 9 */    EL AT "C" NO "hdir/" AT "[RET]" NO "   サブディレクトリの中に入ります\n"
  327.     /* A */    EL AT "Q" NO "uit/" AT "[ESC]" NO "    親ディレクトリに戻ります\n"
  328.     /* B */    EL AT "O" NO "riginal      編集をやり直します\n"
  329.     /* C */    EL AT "W" NO "rite         ディスクに編集結果を書き込みます\n"
  330.     /* D */    EL "\n"
  331.     /* E */    EL "\n"
  332.     /* F */    EL "\n");
  333.  
  334.     #undef    EL
  335.     #undef    AT
  336.     #undef    NO
  337.  
  338.     dm_errmes("何かキーを押してください.");
  339.     putpage(1);
  340. }
  341. /*-------------------------------メインルーチン------------------------------*/
  342. static    void    setglovalvar(struct DIRENTRY far **dirtbl,int dirnum)
  343. {
  344.     Dirtbl = dirtbl;
  345.  
  346.     Dirnum  = dirnum;
  347.     Pagenum = dirnum/96;
  348.     Lastnum = dirnum%96;
  349.  
  350.     if    (Lastnum)    Pagenum++;
  351.     else            Lastnum = 96;
  352.  
  353.     Page = 0;
  354.     Pos  = 0;
  355.  
  356.     Selected = -1;
  357.     Ischanged = 0;
  358. }
  359.  
  360. void    dmmenu(struct DIRENTRY far *parent)
  361. {
  362.     struct DIRENTRY    far *d;
  363.  
  364.     struct    SECTBL        *sectbl;
  365.     auto    int        dirnum;
  366.     struct    DIRENTRY far    **dirtbl;
  367.  
  368. reread:
  369.  
  370.     if    ((dirtbl=readentry(parent,§bl,&dirnum))==NULL)
  371.         return;
  372.  
  373.     setglovalvar(dirtbl,dirnum);
  374.     putpage(1);
  375.  
  376. dmmenu_loop:
  377.  
  378.     switch    (movecursor(1))
  379.     {
  380.     case 'H':
  381.     case 'h':
  382.     case '?':
  383.         cmd_help();
  384.         break;
  385.     case 'I':
  386.     case 'i':
  387.         cmd_insert();
  388.         break;
  389.  
  390.     case 'D':
  391.     case 'd':
  392.         cmd_delete();
  393.         break;
  394.  
  395.     case ' ':
  396.         cmd_exchange();
  397.         break;
  398.  
  399.     case 'S':
  400.     case 's':
  401.         cmd_sort();
  402.         break;
  403.  
  404.     case 'R':
  405.     case 'r':
  406.         if    (Dirtbl[Page*96+Pos]->filename[0]=='\xe5')
  407.             break;
  408.  
  409.         Selected = Page*96+Pos;
  410.         putfilename(Pos);
  411.         if    (dmrename(Selected))
  412.             Ischanged = 1;
  413.  
  414.         Selected = -1;
  415.         putfilename(Pos);
  416.         break;
  417.  
  418.     case 'C':
  419.     case 'c':
  420.     case '\r':
  421.         d = dirtbl[Page*96+Pos];
  422.  
  423.         if    (d->attr&_A_SUBDIR && d->filename[0]!='.')
  424.         {
  425.             int    ischanged_save = Ischanged;
  426.             int    pagesave       = Page;
  427.             int    possave        = Pos;
  428.  
  429.             dmmenu(d);
  430.             setglovalvar(dirtbl,dirnum);
  431.  
  432.             Page = pagesave;
  433.             Pos  = possave;
  434.             Ischanged = ischanged_save;
  435.  
  436.             putpage(1);
  437.         }
  438.         break;
  439.  
  440.     case 'O':
  441.     case 'o':
  442.         if    (isok())
  443.         {
  444.             freesectbl(sectbl);
  445.             free(dirtbl);
  446.             goto reread;
  447.         }
  448.         break;
  449.     case 'Q':
  450.     case 'q':
  451.     case '\033':
  452.         if    (isok())
  453.         {
  454.             freesectbl(sectbl);
  455.             free(dirtbl);
  456.             return;
  457.         }
  458.         break;
  459.     case 'W':
  460.     case 'w':
  461.         writedir(sectbl,dirtbl);
  462.         Ischanged = 0;
  463.         break;
  464.     default:
  465.         putchar('\a');
  466.     }
  467.     goto dmmenu_loop;
  468. }
  469. /*------------------------------スタートアップ-------------------------------*/
  470. #ifdef    CTRLC_BUG    /* LSI C-86の無印Ver3.30はSIG_IGNの処理にバグがある */
  471.     static    void    CTRLC_HANDLER(void)
  472.     {
  473.         signal(SIGINT,CTRLC_HANDLER);
  474.     }
  475. #else
  476.     #define    CTRLC_HANDLER    SIG_IGN
  477. #endif
  478.  
  479. int    main(int argc,char **argv)
  480. {
  481.     int    c;
  482.  
  483.     if    (argc != 2)
  484.     {
  485.     rep:
  486.         printf("ドライブ名は:");
  487.         c = dm_getch();
  488.         if    (c=='\033')
  489.             exit(0);
  490.         else if    (!isalpha(c))
  491.         {
  492.             putchar('\n');
  493.             goto rep;
  494.         }
  495.  
  496.         putchar(c);
  497.         putchar('\n');
  498.     }
  499.     else
  500.         c = argv[1][0];
  501.  
  502.     Drive = toupper(c) - 'A';
  503.  
  504.     if    (Drive<0 || Drive>25)
  505.     {    printf("不正なドライブ名です.\n");
  506.         exit(2);
  507.     }
  508.  
  509.     
  510.  
  511.     if    (getdpb() == -1)
  512.     {    printf("指定されたドライブは存在しません.\n");
  513.         exit(2);
  514.     }
  515.  
  516.     Fat = getfat();
  517.  
  518.     if    (Fat == NULL)
  519.     {    printf("FATの読み込みに失敗しました.\n");
  520.         exit(3);
  521.     }
  522.  
  523.     signal(SIGINT,CTRLC_HANDLER);
  524.  
  525.     mkscreen();
  526.     dmmenu(NULL);
  527.     endscreen();
  528. }
  529.  
  530. void    endscreen(void)
  531. {
  532.     getdpb();    /* DOS内部のバッファを更新するため */
  533.  
  534.     printf( "\033[0v\033[>5l\033[2J"
  535.         "DMOVE86を終了しました.\n");
  536.  
  537.     exit(0);
  538. }
  539.  
  540.